// 39.[DFS递归原来不重复可重复选] 组合总和
// https://leetcode.cn/problems/combination-sum/
//给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target ，
//找出 candidates 中可以使数字和为目标数 target 的 所有 不同组合 ，
//并以列表形式返回。你可以按 任意顺序 返回这些组合。
// candidates 中的 同一个 数字可以 无限制重复被选取 。
//如果至少一个数字的被选数量不同，则两种组合是不同的。
//对于给定的输入，保证和为 target 的不同组合数少于 150 个。
//输入：candidates = [2,3,6,7], target = 7
//输出：[[2,2,3],[7]]
// 2 和 3 可以形成一组候选，2 + 2 + 3 = 7 。注意 2 可以使用多次。
// 7 也是一个候选， 7 = 7 。仅有这两种组合。
//输入: candidates = [2,3,5], target = 8
//输出: [[2,2,2,2],[2,3,3],[3,5]]
//输入: candidates = [2], target = 1
//输出: []
// 题解dfs:
// 个数满,返回
// 目标找到，返回
// idx(跳过或选择加入path)

#include <bits/stdc++.h>
using namespace std;

#define DEBUG_
#ifdef DEBUG_
#define PF(...) printf(__VA_ARGS__)
#define FRE(x)                    \
  freopen("d:/oj/" #x ".in", "r", \
          stdin)  //,freopen("d:/oj/"#x".out","w",stdout)
#define FREC fclose(stdin), fclose(stdout);
#else
#define PF(...)
#define FRE(x)
#define FREC
#endif

class Solution {
  vector<vector<int>> res_;
  vector<int> candidates_;
  void dfs(int target, vector<int> path, size_t idx) {
    if (idx == candidates_.size()) {
      return;
    }
    if (target == 0) {
      res_.push_back(path);
      return;
    }
    dfs(target, path, idx + 1);
    if (target - candidates_[idx] >= 0) {
      path.push_back(candidates_[idx]);
      dfs(target - candidates_[idx], path, idx);
      path.pop_back();
    }
  }

 public:
  vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
    candidates_ = candidates;
    dfs(target, {}, 0);
    return res_;
  }
};

int main() {
  FRE(combsum);
  int target = 0;
  scanf("%d", &target);

  vector<int> cand;
  int tmp = 0;
  while (scanf("%d", &tmp) != EOF) {
    cand.push_back(tmp);
  }
  //    for (auto ss : cand) PF("%d,", ss); PF("\n");
  Solution sol;
  vector<vector<int>> res = sol.combinationSum(cand, target);
  for (auto vt : res) {
    for (auto n : vt) {
      PF("%d,", n);
    }
    PF("\n");
  }
  return 9;
}
